/**
 * 区间询问：假设区间长度为n，每中元素的数量分别是c1,c2,...
 * 本质上就是问： n! / (c1! * c2! * ...)
 * 
 * 考虑增加操作： 新答案 = 原答案 * (n + 1) / (cc + 1)
 * 考虑删除操作： 新答案 = 原答案 * cc / n
 * 注意加加减减
 * O(Nsqrt(N)) N在3E4
 */
#include <bits/stdc++.h>
using namespace std;

#include <bits/extc++.h>
using namespace __gnu_pbds;

using llt = long long;
llt const MOD = 1000000007;

llt qpow(llt a, llt n){
	llt ret = 1;
	while(n){
		if(n & 1) ret = ret * a % MOD;
		a = a * a % MOD;
		n >>= 1;
	}
	return ret;
}

inline llt inv(llt x){return qpow(x, MOD-2LL);}

vector<llt> Inv;
void init(int sz){
    Inv.assign(sz + 1, 0LL);
	for(int i=1;i<=sz;++i) Inv[i] = inv(i);
	return;
}

struct mo_t{ // 莫队算法无修改, 依次调用input(),run(),output()

struct query_t{
    int s;
    int e;
    int idx;
    bool operator < (const query_t & b) const {
        int ln = s / block_size();
        int rn = b.s / block_size();
        if(ln != rn) return ln < rn;
        return e < b.e;
    }
};

using value_t = int;
using answer_t = llt;

vector<value_t> data;      // 原始数组
vector<query_t> questions; // 问题
vector<answer_t> ans;      // 答案

int curLeft, curRight;

llt moans, total;
vector<int> cnt;

static int block_size() {
    static int const BLOCK_SIZE = 300;
    return BLOCK_SIZE;
}

void init(){
	ans.assign(questions.size(), 0);
    sort(questions.begin(), questions.end());

    curLeft = 1; curRight = 0;

    moans = 1LL;
	total = 0LL;
	cnt.assign(data.size() + 1, 0);
}

void insert(int idx){
    moans = moans * ++total % MOD * Inv[++cnt[data[idx]]] % MOD;
}

void remove(int idx){
    moans = moans * cnt[data[idx]]-- % MOD * Inv[total--] % MOD;
}

answer_t answer(){
    return moans;
}

void input(){
    // assert(0);
	int n, q; cin >> n >> q;
	data.assign(n + 1, 0);
	for(int i=1;i<=n;++i) cin >> data[i];
	questions.assign(q, {});
	int k = 0;
	for(auto & q : questions){
		cin >> q.s >> q.e;
		q.idx = k++;
	}
}

void run(){
    init();

    for(const auto & q : questions){
        while(curRight < q.e) insert(++curRight);
        while(curLeft > q.s) insert(--curLeft);
        while(curRight > q.e) remove(curRight--);
        while(curLeft < q.s) remove(curLeft++);
        ans[q.idx] = answer();
    }
}

void output(){
    for(auto i : ans) cout << i << endl;
    // cout << endl;
}

};

mo_t Mo;

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(0);
	init(30000);
    int nofakse; cin >> nofakse;
	while(nofakse--){
		Mo.input();
		Mo.run();
		Mo.output();
	}
    return 0;
}